﻿#include <stdio.h>
#include <string.h>

#include <opencv2/opencv.hpp>
/*
* #include <opencv2/core/core.hpp>
* #include <opencv2/highgui/highgui.hpp>
* #include <opencv2/imgproc/imgproc.hpp>
*/

using namespace cv;

void scale(const char* arg3, const char* arg4, const char* arg5, const char* arg6);//放缩
void rotate(const char* arg2, const char* arg3, const char* arg4);//旋转
void mirror(const char* arg2, const char* arg3, const char* arg4);//镜像

int main(int argc, char* argv[])
{
    for (int i = 0; i < argc; i++)
    {
        if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0)
        {
            printf("\nhelp: Get list of available commands.\n"
                   "Perform image scaling operation : -z -m method some.bmp xxx somenew.bmp\n"
                   "method取值为n/l/c,分别表示最临近插值/双线性插值/三次立方插值\n"
                   "xxx 为 1-999 的百分比数值\n"
                   "Perform image rotation operation : -r some.bmp xxx somenew.bmp\n"
                   "xxx 为 0/90/180/270 四个角度之一\n"
                   "Perform image mirroring operation : -m some.bmp -v/-h somenew.bmp\n"
                   "-h/-v 即 水平/垂直镜像");

            return 0;
        }
    }
    
    if (strcmp(argv[1], "-z") == 0)
    {
        /*
        * 检验参数数量符合要求
        if (argc != 7)
        {
            printf("Wrong number of parameters.");
            return 0;
        }
        */

        scale(argv[3], argv[4], argv[5], argv[6]);
    }
    else if (strcmp(argv[1], "-r") == 0)
    {
        /*
        * 检验参数数量符合要求
        if (argc != 5)
        {
            printf("Wrong number of parameters.");
            return 0;
        }
        */
        
        rotate(argv[2],argv[3],argv[4]);
    }
    else if (strcmp(argv[1], "-m") == 0)
    {
        /*
        * 检验参数数量符合要求
        if (argc != 5)
        {
            printf("Wrong number of parameters.");
            return 0;
        }
        */

        mirror(argv[2], argv[3], argv[4]);
    }


    return 0;
}

//图像放缩
void scale(const char* arg3,const char* arg4,const char* arg5,const char* arg6)
{
    //读取图像
    Mat image = imread(arg4);

    /*
    *转化为灰度图
    Mat imgray;
    cvtColor(image, imgray, COLOR_BGR2GRAY);
    */

    //读取放缩系数
    char* pEnd;
    double rate = strtod(arg5, &pEnd) / 100;
    
    Mat img;//定义转换后的图像
    //读取放缩方法
    //执行放缩操作
    if (strcmp(arg3, "n") == 0)
        resize(image, img, Size(0, 0), rate, rate, INTER_NEAREST);//最临近插值
    else if (strcmp(arg3, "l") == 0)
        resize(image, img, Size(0, 0), rate, rate, INTER_LINEAR);//双线性插值
    else if (strcmp(arg3, "c") == 0)
        resize(image, img, Size(0, 0), rate, rate, INTER_CUBIC);//双三次插值

    //储存为新文件
    imwrite(arg6, img);

    //释放内存
    img.release();
    image.release();
}

//图像旋转
void rotate(const char* arg2, const char* arg3, const char* arg4)
{
    //读取图像
    Mat image = imread(arg2);

    /*
    *转化为灰度图
    Mat imgray;
    cvtColor(image, imgray, COLOR_BGR2GRAY);
    */

    //读取旋转角度
    char* pEnd;
    double angle = strtod(arg3, &pEnd);

    // 旋转中心点
    Point2f center(image.cols / 2.0, image.rows / 2.0);

    // 获取旋转后图像的新尺寸
    //操作与放缩类似，放缩采用fx，fy，也可采用如下的dsize进行
    double scale = 1.0;
    Size size = image.size();
    
    // 获取旋转矩阵（包含旋转变换）
    Mat rotMat = getRotationMatrix2D(center, angle, scale);

    // 执行旋转操作
    Mat img;//定义转化后的图像
    warpAffine(image, img, rotMat, size);

    //储存为新文件
    imwrite(arg4, img);

    //释放内存
    img.release();
    image.release();
}

//图像镜像
void mirror(const char* arg2, const char* arg3, const char* arg4)
{
    //读取图像
    Mat image = imread(arg2);

    /*
    *转化为灰度图
    Mat imgray;
    cvtColor(image, imgray, COLOR_BGR2GRAY);
    */

    Mat img;//定义转换后的图像
    //读取镜像方式
    //执行镜像操作
    if (strcmp(arg3, "-v") == 0)//垂直
        flip(image, img, 1);
    else if (strcmp(arg3, "-h") == 0)//水平
        flip(image, img, 0);

    //储存为新文件
    imwrite(arg4, img);

    //释放内存
    img.release();
    image.release();
}
